package com.cms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cms.entity.Role;
import com.cms.service.RoleService;

@Service
public class RoleServiceImpl extends BaseServiceImpl implements RoleService {

	private static final Logger LOG = LoggerFactory
			.getLogger(RoleService.class);

	@Cacheable(value="myCache")
	@Transactional(readOnly = true)
	public List<Role> listRoles() {
		DetachedCriteria dc = DetachedCriteria.forClass(Role.class)
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return baseDao.findByCriteria(dc);
	}

	@Transactional(readOnly = true)
	public Role getRole(Integer id) {
		return baseDao.get(Role.class, id);
	}

	@Transactional
	public boolean saveRole(Role role) {
		try {
			if (role.getCreateDate() == null) {
				role.setCreateDate(new Date());
			}
			baseDao.save(role);
			return true;
		} catch (Exception e) {
			LOG.error(e.toString());
		}
		return false;
	}

	@Transactional
	public boolean removeById(Integer id) {
		try {
			Role r = baseDao.load(Role.class, id);
			baseDao.delete(r);
			return true;
		} catch (Exception e) {
			LOG.error(e.toString());
		}
		return false;
	}

	@Transactional(readOnly = true)
	public List<Role> listDateRoles(String authority, String description,
			Integer from, Integer length) {

		if (from == null) {
			from = 0;
		}
		if (length == null) {
			length = 15;
		}
		// 查询结果
		List<Object> any = new ArrayList<Object>();
		any.add(Transformers.aliasToBean(Role.class));
		any.add(Restrictions.ne("authority", "ROLE_ADMIN"));
		if (StringUtils.isNotBlank(authority)) {
			any.add(Restrictions.eq("authority", authority.trim()));
		}
		if (StringUtils.isNotBlank(description)) {
			any.add(Restrictions.like("description", description.trim(),
					MatchMode.ANYWHERE));
		}
		any.add(Projections.property("id").as("id"));
		any.add(Projections.property("authority").as("authority"));
		any.add(Projections.property("description").as("description"));
		any.add(Projections.property("createDate").as("createDate"));

		return baseDao.findByAny(Role.class, from, length, any.toArray());
	}

	@Transactional
	public void update(Role role) {
		baseDao.update(role);
	}

	@Transactional
	public Long getCount(String authority, String description) {
		// 查询结果
		List<Criterion> any = new ArrayList<Criterion>();
		// 查询条件
		if (StringUtils.isNotBlank(authority)) {
			any.add(Restrictions.eq("authority", authority.trim()));
		}
		return baseDao.countByAny(Role.class,
				any.toArray(new Criterion[any.size()]));
	}

	/**
	 * 根据角色名，查询角色
	 * 
	 * @param authority
	 * @return
	 */
	@Transactional
	public Role queryRoleByAuthority(String authority) {
		if (StringUtils.isNotBlank(authority)) {
			String hql = "from Role where authority=?";
			List<Role> roles = baseDao
					.hqlQuery(hql, new Object[] { authority });
			if (roles != null && roles.size() > 0) {
				return roles.get(0);
			}
		}
		return null;
	}

}
